/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
function judgeTypeFnCreator(type: string) {
  const toString = Object.prototype.toString
  return function isType(o: any) {
    return toString.call(o) === `[object ${type}]`
  }
}

export const isFunc = judgeTypeFnCreator('Function')
export const isUndef = judgeTypeFnCreator('Undefined')
export const isArray = judgeTypeFnCreator('Array')
export const isString = judgeTypeFnCreator('String')
export const isObject = judgeTypeFnCreator('Object')
export const isNumber = judgeTypeFnCreator('Number')

/**
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
// eslint-disable-next-line @typescript-eslint/ban-types
export function debounce(func: Function, wait: number, immediate?: boolean): any {
  let timeout: NodeJS.Timeout | null, args: any, context: any, timestamp: number, result: any

  const later = function () {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last)
    } else {
      timeout = null
      // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args)
        if (!timeout) context = args = null
      }
    }
  }

  return function (...args: any) {
    context = this
    timestamp = +new Date()
    const callNow = immediate && !timeout
    // 如果延时不存在，重新设定延时
    if (!timeout) timeout = setTimeout(later, wait)
    if (callNow) {
      result = func.apply(context, args)
      context = args = null
    }
    return result
  }
}

export function throttle(
  func: { apply: (arg0: any, arg1: IArguments) => void },
  wait: number,
): any {
  let previous = 0
  return function () {
    const now = Date.now()
    // eslint-disable-next-line @typescript-eslint/no-this-alias
    const context = this
    // eslint-disable-next-line prefer-rest-params
    const args = arguments
    if (now - previous > wait) {
      func.apply(context, args)
      previous = now
    }
  }
}

export function getCalendarByYyMm(yy: number, mm: number): any {
  const weekString = '日一二三四五六'
  const _arr = []
  let startDate = new Date(yy, mm - 1, 1)
  while (1 === 1) {
    const dd = startDate.getDate()
    _arr.push({
      yy,
      mm,
      dd,
      cycle: weekString[startDate.getDay()],
    })
    startDate = new Date(startDate.valueOf() + 1000 * 60 * 60 * 24)
    if (startDate.getMonth() + 1 != mm) {
      break
    }
  }
  return _arr
}

// 深冻结函数.
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export function deepFreeze(obj: any): any {
  // 取回定义在obj上的属性名
  const propNames = Object.getOwnPropertyNames(obj)
  // 在冻结自身之前冻结属性
  propNames.forEach(function (name) {
    const prop = obj[name]
    // 如果prop是个对象，冻结它
    if (typeof prop == 'object' && prop !== null) deepFreeze(prop)
  })
  // 冻结自身(no-op if already frozen)
  return Object.freeze(obj)
}

//格式化取括号内容
export function parentheses(obj: any): any {
  const rt = /(.+)?(?:\(|（)(.+)(?=\)|）)/.exec(obj)
  return rt && rt[2]
}
// 补0
export function paddingZero(val: string | number): string {
  val = val + ''
  if (!val) {
    return val
  }
  if (String(val).length >= 2) {
    return val
  }
  return `0${val}`
}
//获取当月最后一天
export function getCurrentMonthLastDay() {
  const current = new Date()
  let currentMonth = current.getMonth()
  const nextMonth = ++currentMonth
  const nextMonthDayOne = new Date(current.getFullYear(), nextMonth, 1)
  const minusDate = 1000 * 60 * 60 * 24
  return new Date(nextMonthDayOne.getTime() - minusDate)
}

//格式化时间
export function getFormatDate(date: any) {
  console.log('_Data', date.split('-'))
  const newDate = date.split('-')
  const time = newDate[0] + newDate[1] + newDate[2]
  return time
}
